package com.gitee.apanlh.util.algorithm.encrypt.symmetric;

import com.gitee.apanlh.util.algorithm.KeyUtils;
import com.gitee.apanlh.util.algorithm.encrypt.AlgorithmMode;
import com.gitee.apanlh.util.algorithm.encrypt.AlgorithmPadding;

/**
 * 	DES对称加密算法
 * 	<br>提供了DES加密和解密的功能
 * 	<br>可自定义key、iv、分组模式、填充模式等等来完成创建不同的DES实例
 *
 * 	<p>参数说明：
 * 	<br>- key: 密钥的字节数组，用于加密和解密数据
 * 	<br>- iv: 初始化向量的字节数组，用于CBC模式。ECB模式不需要初始化向量，传入null即可
 * 	<br>- algorithmMode: 加密器模式，如ECB、CBC等
 * 	<br>- algorithmPadding: 加密填充模式，如PKCS5、PKCS7等
 *
 * 	<p>注意事项：
 * 	<br>- ECB模式下不需要初始化向量(iv)，传入null即可。
 * 	<br>- 对于DES算法固定为64位（8字节），初始化向量(iv)长度应该与加密算法块大小一致
 * 	<br>- 填充算法PKCS5/PKCS7通常适用于大多数情况，但在特殊需求下可能需要使用其他填充算法
 * 	<br>- 使用CBC等带有初始化向量的模式时，必须确保密钥和初始化向量的安全存储和传输
 * 	<br>- 对于不同的加密器模式和填充算法，可能需要在解密时手动进行去除填充操作
 *
 * 	<p>示例用法：
 * 	<pre>
 * 	注意:静态方法会更方便构建
 * 	使用默认的ECB模式和PKCS5填充算法，随机生成64位密钥
 * 	DES des1 = new DES();
 * 	// 使用指定的密钥和初始化向量(iv)，采用默认的CBC模式和PKCS5填充算法
 * 	DES des2 = new DES(KeyUtils.generate64(), RandomUtils.generate64());
 * 	</pre>
 *
 * 	@author Pan
 */
public class DES extends BouncyCastleSymmetricAbstract {

    /**
     * 	构造函数-ECB模式加密器
     * 	<br>默认DES/ECB/PKCS5Padding算法
     * 	<br>随机64位密钥长度
     * 	
     * 	@author Pan
     */
    public DES() {
        this(KeyUtils.generate64());
    }
    
    /**
     * 	构造函数-ECB模式加密器
     * 	<br>默认DES/ECB/PKCS5Padding算法
     * 	
     * 	@author Pan
     * 	@param 	key 密钥
     */
    public DES(byte[] key) {
        super(key, null, SymmetricType.DES);
    }
    
    /**
	 * 	构造函数-ECB模式加密器 
	 *  <br>自定义密钥
	 *  <br>自定义填充方法
	 * 
	 * @author Pan
	 * @param  key              密钥
	 * @param  algorithmPadding 加密填充模式
	 */
    public DES(byte[] key, AlgorithmPadding algorithmPadding) {
    	super(key, null, SymmetricType.DES, AlgorithmMode.ECB, algorithmPadding);
	}
    
    /**
     * 	构造函数-CBC模式加密器
     * 	<br>默认DES/CBC/PKCS5Padding算法
     * 	<br>自定义密钥 
	 *	<br>自定义向量
     * 
     * 	@author Pan
     * 	@param 	key 密钥
     * 	@param 	iv  初始化向量字节
     */
    public DES(byte[] key, byte[] iv) {
        this(key, iv, AlgorithmPadding.PKCS5);
    }
    
    /**
	 * 	构造函数-CBC模式加密器 
	 *  <br>自定义密钥
	 *  <br>自定义向量 
	 *  <br>自定义填充方法
	 * 
	 * @author Pan
	 * @param  key              密钥
	 * @param  iv               初始化向量
	 * @param  algorithmPadding 加密填充模式
	 */
    public DES(byte[] key, byte[] iv, AlgorithmPadding algorithmPadding) {
    	this(key, iv, AlgorithmMode.CBC, algorithmPadding);
	}
    
	/**
	 * 	构造函数-自定义模式加密器
	 *  <br>自定义密钥
	 *  <br>自定义向量 
	 *  <br>自定义加密器模式
	 *  <br>自定义填充方法
	 * 
	 * 	@author Pan
	 * 	@param 	key              密钥
	 * 	@param 	iv               初始化向量
	 * 	@param 	algorithmMode    加密器模式
	 * 	@param 	algorithmPadding 加密填充模式
	 */
	public DES(byte[] key, byte[] iv, AlgorithmMode algorithmMode, AlgorithmPadding algorithmPadding) {
		super(key, iv, SymmetricType.DES, algorithmMode, algorithmPadding);
	}
	
	/**
	 * 	构建-自定义模式加密器
	 *  <br>自定义密钥
	 *  <br>自定义向量 
	 *  <br>自定义加密器模式
	 *  <br>自定义填充方法
	 * 
	 * 	@author Pan
	 * 	@param 	key              密钥
	 * 	@param 	iv               初始化向量
	 * 	@param 	algorithmMode    加密器模式
	 * 	@param 	algorithmPadding 加密填充模式
	 *  @return DES
	 */
	public static DES create(byte[] key, byte[] iv, AlgorithmMode algorithmMode, AlgorithmPadding algorithmPadding) {
		return new DES(key, iv, algorithmMode, algorithmPadding);
	}
	
	/**
     * 	构建-ECB模式加密器
     * 	<br>默认DES/ECB/PKCS5Padding算法
     * 	<br>随机64位密钥长度
     * 	
     * 	@author Pan
     *  @return DES
     */
	public static DES createEcb() {
		return new DES();
	}
	
	/**
     * 	构建-ECB模式加密器
     * 	<br>默认DES/ECB/PKCS5Padding算法
     * 	
     * 	@author Pan
     * 	@param 	key 密钥
     *  @return DES
     */
	public static DES createEcb(byte[] key) {
		return new DES(key);
	}
	
	/**
	 * 	构建-ECB模式加密器 
	 *  <br>自定义密钥
	 *  <br>自定义填充方法
	 * 
	 * @author Pan
	 * @param  key              密钥
	 * @param  algorithmPadding 加密填充模式
	 *  @return DES
	 */
	public static DES createEcb(byte[] key, AlgorithmPadding algorithmPadding) {
		return new DES(key, algorithmPadding);
	}
	
	/**
     * 	构建-CBC模式加密器
     * 	<br>默认DES/CBC/PKCS5Padding算法
     * 	<br>随机64位密钥 
	 *	<br>随机64位向量密钥长度
     * 
     * 	@author Pan
     *  @return DES
     */
	public static DES createCbc() {
		return createCbc(KeyUtils.generate64(), KeyUtils.generate64(), AlgorithmPadding.PKCS5);
	}
	
	/**
     * 	构建-CBC模式加密器
     * 	<br>默认DES/CBC/PKCS5Padding算法
     * 	<br>自定义密钥 
	 *	<br>随机64位向量密钥长度
     * 
     * 	@author Pan
     * 	@param 	key 密钥
     *  @return DES
     */
	public static DES createCbc(byte[] key) {
		return createCbc(key, KeyUtils.generate64(), AlgorithmPadding.PKCS5);
	}
	
	/**
     * 	构建-CBC模式加密器
     * 	<br>默认DES/CBC/PKCS5Padding算法
     * 	<br>自定义密钥 
	 *	<br>自定义向量密钥长度
     * 
     * 	@author Pan
     * 	@param 	key 密钥
     * 	@param 	iv  初始化向量字节
     *  @return DES
     */
	public static DES createCbc(byte[] key, byte[] iv) {
		return createCbc(key, iv, AlgorithmPadding.PKCS5);
	}
	
	/**
	 * 	构建-CBC模式加密器 
	 *  <br>自定义密钥
	 *  <br>自定义向量 
	 *  <br>自定义填充方法
	 * 
	 * @author Pan
	 * @param  key              密钥
	 * @param  iv               初始化向量
	 * @param  algorithmPadding 加密填充模式
	 * @return DES
	 */
	public static DES createCbc(byte[] key, byte[] iv, AlgorithmPadding algorithmPadding) {
		return new DES(key, iv, algorithmPadding);
	}
}
